/*
 * @Author: 孙文豪
 * @Description: 鼠标移入提示框指令
 * @Date: 2022-12-08 11:40:22
 * @LastEditTime: 2023-05-08 10:03:51
 * @LastEditors: 孙文豪
 */
export default function MoveTips_v() {
  let timer = null; // 定时器
  let tipsEle = null; //保存提示元素
  // 初始化创建弹窗
  const init = (el, binding) => {
    let tipsText = '提示信息'
    // 可配置默认样式
    let configAttr = {
      vText: tipsText,
      vMaxWidth: '200px',  // 最大宽度
      vColor: '#fff',   // 文本颜色
      vBorderColor: 'none',  //边框颜色
      vRadius: '5px',   // 圆角
      vBackground: '#000',   // 背景色
      vFontSize: '14px',    // 字号
      vPadding: '10px 20px',  // 边距
      vTime: 500,
      vMoveHide: false    //鼠标移动隐藏弹窗
    }
    const configParam = binding.value
    if (configParam instanceof Object) {
      // 对象配置，替换默认属性值
      configAttr = Object.assign(configAttr, configParam)
      tipsText = String(configParam.vText)
    } else {
      // 字符串，设置文本内容
      tipsText = String(configParam)
    }
    // 监听鼠标移动
    el.addEventListener('mousemove', function (e) {
      // 判断是否有提示，有就清楚元素和变量
      // 如果vMoveHide为false,鼠标移动就不删除弹窗
      if (isInPage(tipsEle) && configAttr.vMoveHide) {
        document.body.removeChild(tipsEle);
        tipsEle = null;
      }
      // 存在弹窗就不在创建
      if (isInPage(tipsEle)) return
      // 清除定时器
      clearTimeout(timer);
      // 执行鼠标停止后的定时器 binding中增加定时器,方便其他生命周期使用
      timer = setTimeout(() => {
        const { vMaxWidth, vColor, vRadius, vFontSize, vPadding, vBackground, vBorderColor } = configAttr
        // el.style.position = 'relative';      // 先设置目标元素绝对定位，方便子级相对父级定位,暂不使用,子元素挂在至body
        tipsEle = document.createElement('div');    // 创建提示框盒子元素
        tipsEle.setAttribute('id', 'tttips-ele-tttips');  //设置id
        tipsEle.style.width = vMaxWidth;      //最大宽度    设置盒子宽度（提示框最大宽度）（必须给定宽度值，不然absolute宽度会受父级元素宽度影响）
        let tipsTextEle = document.createElement('p');  // 在创建文本元素
        tipsTextEle.innerHTML = tipsText;  // 设置文本内容
        tipsTextEle.style.display = 'inline-block'
        tipsTextEle.style.textAlign = 'justify'
        tipsTextEle.style.caretColor = 'transparent';
        tipsTextEle.style.fontSize = vFontSize;   //以下是样式
        tipsTextEle.style.color = vColor;
        tipsTextEle.style.padding = vPadding;
        tipsTextEle.style.background = vBackground;
        tipsTextEle.style.borderRadius = vRadius;
        tipsTextEle.style.border = vBorderColor;
        tipsEle.appendChild(tipsTextEle)  // 文本元素加入提示框元素中
        document.body.appendChild(tipsEle); // 将提示元素增加到body中
        tipsEle.style.position = 'fixed'; //设置提示元素相对父元素定位
        tipsEle.style.zIndex = '9999';
        // 下面是判断弹窗边界情况
        // 获取需要控制边界的父级元素
        const parentEle = configParam.parentId && document.getElementById(configParam.parentId)
        let pageW, pageH, parentTop, parentLeft
        if (parentEle) {
          const parentEleInfo = parentEle.getBoundingClientRect()
          parentTop = parentEleInfo.top   // 父元素相对页面顶部距离
          parentLeft = parentEleInfo.left   // 父元素相对页面左侧距离
          pageW = parentEle.offsetWidth  //父级宽度
          pageH = parentEle.offsetHeight   //父级高度
        } else {
          parentTop = 0    // 相对页面就设置0
          parentLeft = 0
          pageW = document.body.offsetWidth   //页面宽度
          pageH = document.body.offsetHeight   //页面高度
        }
        let mouseY = e.clientY   //top
        let mouseX = e.clientX   //left
        const tipsW = tipsTextEle.offsetWidth    // 弹窗宽度
        const isOutR = (mouseX - parentLeft + tipsW + 10) > pageW   //是否超出右边 鼠标位置+弹窗宽度 > 页面宽度
        const tipsH = tipsTextEle.offsetHeight    // 弹窗高度
        const isOutB = (mouseY - parentTop + tipsH + 10) > pageH   //是否超出底部 鼠标位置+弹窗高度 > 页面高度
        // 超出右侧边界  鼠标位置 - 弹窗宽度 -10 向左侧展示
        if (isOutR) {
          mouseX = mouseX - tipsW - 10
        }
        // 超出底部边界  鼠标位置 - 弹窗高度 -10 向上侧展示
        if (isOutB) {
          mouseY = mouseY - tipsH - 10
        }
        tipsEle.style.top = `${mouseY + 10}px`; //设置提示框位置
        tipsEle.style.left = `${mouseX + 10}px`;
      }, configAttr.vTime);
    });
    // 移出时删除元素
    el.addEventListener('mouseleave', deleteTipsEle);
    // 监听点击事件清除弹窗（解决点击后切换页面还显示弹窗bug,符合业务场景）
    el.addEventListener('click', deleteTipsEle);
  }
  // 删除提示框元素
  const deleteTipsEle = () => {
    clearTimeout(timer);
    if (isInPage(tipsEle)) {
      document.body.removeChild(tipsEle);
      tipsEle = null;
    }
  }
  // 判断当前节点是不是body的子节点
  const isInPage = (node) => {
    return (node === document.body) ? false : document.body.contains(node);
  }
  return {
    // 自定义指令
    // 参数更新 vue2对应生命周期函数update
    updated(el, binding) {
      init(el, binding)
    },
    // 挂载时 vue2对应生命周期函数bind
    mounted(el, binding) {
      init(el, binding)
    },
    // 绑定指令的组件销毁时,清除提示元素 vue2对应生命周期函数unbind
    beforeUnmount(el, binding) {
      clearTimeout(timer);
      let ele = document.getElementById('tttips-ele-tttips')
      if (ele) {
        document.body.removeChild(ele);
      }
    }
  };
}
    // const MoveTips_v =
    // export default {
    //     MoveTips_v
    // }
      // tipsEle.style.width = 'fit-content'   // 设置子元素宽度自适应

